package com.px.user.controller;

import com.px.common.core.RespCode;
import com.px.common.core.Response;
import com.px.user.entity.Course;
import com.px.user.mapper.CourseMapper;
import com.px.user.model.ActionModel;
import com.px.user.model.PagingResp;
import com.px.user.service.TeacherService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import io.swagger.annotations.Authorization;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.Authentication;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import java.security.Principal;
import java.sql.Timestamp;
import java.util.Arrays;
import java.util.List;

@Slf4j
@Validated
@RestController
@Api(value = "课程管理", tags = {"课程管理"})
@RequestMapping("/course")
public class CourseController {

    @Value("${px.live.push}")
    private String streamPushBaseUrl;
    @Value("${px.live.pull}")
    private String streamFetchBaseUrl;

    @Autowired
    private CourseMapper courseMapper;

    @Autowired
    private TeacherService teacherService;

    @PostMapping
    @PreAuthorize("hasAnyAuthority('TEACHER','ROOMADMIN','ADMIN')")
    @ApiOperation(value = "课程创建", authorizations = {@Authorization(value = "token")}, tags = {"课程"})
    public Response coursePost(
            @Validated(ActionModel.Insert.class) @RequestBody Course course, Principal principal) {
        String roomIds = course.getRoomIds();
        for (String r : Arrays.asList(roomIds.split("\\s*,\\s*"))) {
            course.setQroomId(Long.valueOf(r));
            if (courseMapper.roomCourseCheck(course) != null)
                return Response.fail(RespCode.COURSE_CONFLICT, r);
        }
        course.setCreatorId(Long.valueOf(principal.getName()));
        if (course.getRoomIds() != null)
            course.setRoomIds(course.roomIds2json(course.getRoomIds()));
        course.setPushSource(streamPushBaseUrl + course.getTeacherId());
        course.setFetchSource(streamFetchBaseUrl + course.getTeacherId() + ".flv");
        courseMapper.insert(course);
        return Response.success(course.getId());
    }

    @GetMapping("/search")
    @PreAuthorize("hasAnyAuthority('ADMIN')")
    @ApiOperation(value = "课程搜索", authorizations = {@Authorization(value = "token")}, tags = {"课程"})
    public Response<PagingResp<Course>> searchGet(
            @ApiParam(value = "开始时间戳", example = "1566805792293") @RequestParam(value = "start", required = false) Long qstart,
            @ApiParam(value = "结束时间戳", example = "1566805792293") @RequestParam(value = "end", required = false) Long qend,
            @ApiParam(value = "id") @RequestParam(value = "id", required = false) Integer id,
            @ApiParam(value = "老师id") @RequestParam(value = "teacherId", required = false) Long teacherId,
            @ApiParam(value = "房间id") @RequestParam(value = "qroomId", required = false) Long qroomId,
            @ApiParam(value = "房间名称(模糊匹配)") @RequestParam(value = "roomName", required = false) String roomName,
            @ApiParam(value = "排序字段(倒序)", example = "updateTime") @RequestParam(value = "orderField", required = false, defaultValue = "createTime") String orderField,
            @ApiParam(value = "页码", example = "0") @RequestParam(value = "page", required = false, defaultValue = "0") @Min(0) Integer page,
            @ApiParam(value = "返回数量", example = "10") @RequestParam(value = "limit", required = false, defaultValue = "10") @Min(1) Integer limit) {
        Course qCourse = Course.builder()
                .qstart(qstart == null ? null : new Timestamp(qstart))
                .qend(qend == null ? null : new Timestamp(qend))
                .id(id)
                .teacherId(teacherId)
                .qroomId(qroomId)
                .roomName(roomName == null ? null : String.join(roomName, "%", "%"))
                .orderField(orderField)
                .startIndex(page * limit)
                .limit(limit)
                .build();

        List<Course> courses = courseMapper.paging(qCourse);
        courses.forEach(c -> c.setRoomIds(c.json2roomIds(c.getRoomIds())));
        return Response.success(
                PagingResp.<Course>builder().itemCount(courseMapper.pagingCount(qCourse)).items(courses).build());
    }

    @GetMapping
    @ApiOperation(value = "课程所有", notes = "游客使用", tags = {"课程"})
    public Response<List<Course>> courseAllGet(
            @ApiParam(value = "房间ID", example = "4") @RequestParam(value = "roomId", required = false) Long roomId,
            @ApiParam(value = "讲师ID", example = "4") @RequestParam(value = "teacherId", required = false) Long teacherId,
            @ApiParam(value = "截止时间", example = "1566805792293") @RequestParam(value = "beforeTime") Long beforeTime) {
        if (roomId == null && teacherId == null)
            return Response.fail(RespCode.PARA_ERROR, null);

        Timestamp qend = new Timestamp(beforeTime);
        List<Course> courses;
        if (roomId != null)
            courses = courseMapper.findByRoomId(Course.builder().qroomId(roomId).qend(qend).build());
        else
            courses = courseMapper.findByTeacherId(Course.builder().teacherId(teacherId).qend(qend).build());
        courses.forEach(c -> c.setRoomIds(c.json2roomIds(c.getRoomIds())));
        return Response.success(courses);
    }

    @PutMapping
    @PreAuthorize("hasAnyAuthority('TEACHER','ROOMADMIN','ADMIN')")
    @ApiOperation(value = "课程更新", authorizations = {@Authorization(value = "token")}, tags = {"课程"})
    public Response coursePut(
            @Validated(ActionModel.Update.class) @RequestBody Course course, Principal principal) {

        // 检查课程冲突状态
        String roomIds = course.getRoomIds();
        if (roomIds != null)
            for (String r : Arrays.asList(roomIds.split("\\s*,\\s*"))) {
                course.setQroomId(Long.valueOf(r));
                if (courseMapper.roomCourseCheckExcludeMe(course) != null)
                    return Response.fail(RespCode.COURSE_CONFLICT, r);
            }

        course.setCreatorId(Long.valueOf(principal.getName()));
        if (roomIds != null)
            course.setRoomIds(course.roomIds2json(roomIds));

        if (course.getTeacherId() != null){
            course.setPushSource(streamPushBaseUrl + course.getTeacherId());
            course.setFetchSource(streamFetchBaseUrl + course.getTeacherId() + ".flv");
        }
        courseMapper.update(course);
        return Response.success(null);
    }

    @DeleteMapping("/{id}")
    @PreAuthorize("hasAnyAuthority('TEACHER','ROOMADMIN','ADMIN')")
    @ApiOperation(value = "课程删除", authorizations = {@Authorization(value = "token")}, notes = "讲师/房管/总管使用", tags = {"课程"})
    public Response courseDelete(@ApiParam(value = "课程ID", example = "4") @PathVariable("id") Integer id,
                                 Authentication authentication) {
        if (id == null)
            return Response.fail(RespCode.PARA_ERROR, null);
        teacherService.courseDelete(id, authentication);
        return Response.success(null);
    }
}
